package com.xyazm.order.statemachine.action.order.cancel;

import com.xyazm.common.enums.OrderStatusChangeEnum;
import com.xyazm.common.enums.OrderStatusEnum;
import com.xyazm.order.dao.OrderInfoDAO;
import com.xyazm.order.dao.OrderOperateLogDAO;
import com.xyazm.order.domain.dto.CancelOrderAssembleDTO;
import com.xyazm.order.domain.dto.OrderInfoDTO;
import com.xyazm.order.domain.entity.OrderInfoDO;
import com.xyazm.order.domain.entity.OrderOperateLogDO;
import com.xyazm.order.statemachine.action.OrderStateAction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 订单取消抽象 Action
 * @author xuyou
 * @date 2023年02月24日 21:36
 */
@Slf4j
public abstract class AbstractOrderCancelAction extends OrderStateAction<CancelOrderAssembleDTO> {

    @Autowired
    private OrderInfoDAO orderInfoDAO;

    @Autowired
    private OrderOperateLogDAO orderOperateLogDAO;

    @Override
    protected OrderInfoDTO onStateChangeInternal(OrderStatusChangeEnum event, CancelOrderAssembleDTO context) {

        OrderInfoDTO orderInfoDTO = context.getOrderInfoDTO();
        String orderId = context.getOrderId();

        // 1、根据orderId查询全部主单和子单
        List<OrderInfoDO> allOrderList = orderInfoDAO.getAllByOrderId(orderId);

        // 2、封装操作数据
        List<OrderInfoDO> updateOrderList = new ArrayList<>();
        List<OrderOperateLogDO> orderOperateLogDOList = new ArrayList<>();
        for (OrderInfoDO orderInfo : allOrderList) {
            //  更新订单数据
            OrderInfoDO updateOrder = new OrderInfoDO();
            updateOrder.setId(orderInfo.getId());
            updateOrder.setOrderId(orderInfo.getOrderId());
            updateOrder.setCancelType(context.getCancelType());
            updateOrder.setOrderStatus(OrderStatusEnum.CANCELLED.getCode());
            updateOrder.setCancelTime(new Date());
            updateOrderList.add(updateOrder);

            // 订单操作日志数据
            OrderOperateLogDO orderOperateLogDO = new OrderOperateLogDO();
            orderOperateLogDO.setOrderId(orderInfo.getOrderId());
            orderOperateLogDO.setPreStatus(getPreStatus());
            orderOperateLogDO.setCurrentStatus(OrderStatusEnum.CANCELLED.getCode());
            setOperateTypeAndRemark(orderOperateLogDO, context.getCancelType());
            orderOperateLogDOList.add(orderOperateLogDO);
        }

        // 3、更新订单状态为已取消
        orderInfoDAO.updateBatchById(updateOrderList);
        log.info("更新订单信息OrderInfo状态: orderId:{},status:{}", orderInfoDTO.getOrderId(), orderInfoDTO.getOrderStatus());

        // 4、新增订单操作操作日志表
        orderOperateLogDAO.saveBatch(orderOperateLogDOList);
        log.info("新增订单操作日志OrderOperateLog状态,orderId:{}", orderInfoDTO.getOrderId());

        //  5、返回标准订单信息
        return orderInfoDTO;
    }
    private Integer getPreStatus() {
        return event().getFromStatus().getCode();
    }

    /**
     * 设置操作类型和备注
     */
    protected abstract void setOperateTypeAndRemark(OrderOperateLogDO operateLogDO, Integer cancelType);

}
